/**********************************************************************
* @file		gpio.c
* @brief	Contains Base functions support for GPIO firmware MT7628
* @version	1.0
* @date		7. Jul. 2010
* @author	Ruihuan ZHANG
*
* Copyright (C) Nanjing Sandemarine Electric Co., Ltd
* All rights reserved.
*
***********************************************************************
* Note:并不是所有的GPIO均可以有效的设置，你必须事先在GPIO驱动中将对应的GPIO复用功能连接到GPIO功能，
* 而不是其他外设功能
**********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ioctl.h>
#include "gpio.h"


#define	RALINK_GPIO_SET_DIR		0x01
#define RALINK_GPIO_SET_DIR_IN		0x11
#define RALINK_GPIO_SET_DIR_OUT		0x12
#define	RALINK_GPIO_READ		0x02
#define	RALINK_GPIO_WRITE		0x03
#define	RALINK_GPIO_SET			0x21
#define	RALINK_GPIO_CLEAR		0x31
#define	RALINK_GPIO_READ_INT		0x02 //same as read
#define	RALINK_GPIO_WRITE_INT		0x03 //same as write
#define	RALINK_GPIO_SET_INT		0x21 //same as set
#define	RALINK_GPIO_CLEAR_INT		0x31 //same as clear
#define RALINK_GPIO_ENABLE_INTP		0x08
#define RALINK_GPIO_DISABLE_INTP	0x09
#define RALINK_GPIO_REG_IRQ		0x0A
#define RALINK_GPIO_LED_SET		0x41



#define	RALINK_GPIO6332_SET_DIR		0x51
#define RALINK_GPIO6332_SET_DIR_IN	0x13
#define RALINK_GPIO6332_SET_DIR_OUT	0x14
#define	RALINK_GPIO6332_READ		0x52
#define	RALINK_GPIO6332_WRITE		0x53
#define	RALINK_GPIO6332_SET		0x22
#define	RALINK_GPIO6332_CLEAR		0x32

#define	RALINK_GPIO9564_SET_DIR		0x61
#define RALINK_GPIO9564_SET_DIR_IN	0x15
#define RALINK_GPIO9564_SET_DIR_OUT	0x16
#define	RALINK_GPIO9564_READ		0x62
#define	RALINK_GPIO9564_WRITE		0x63
#define	RALINK_GPIO9564_SET		0x23
#define	RALINK_GPIO9564_CLEAR		0x33





#define GPIO_DEV	"/dev/gpio"


/*********************************************************************//**
 * @brief		Set Direction for GPIO port.
 * @param[in]	portNum		Port Number value
 *  						- 0(gpio3100):	GPIO bit 0 - 31
 *							- 1(gpio6332):	GPIO bit 32 - 63
 *							- 2(gpio9564): 	GPIO bit 64 - 95
 * @param[in]	bitValue	Value that contains all bits to set direction,
 * 							in range from 0 to 0xFFFFFFFF.
 * 							example: value 0x5 to set direction for bit 0 and bit 1.
 * @param[in]	dir			Direction value, should be:
 * 							- 0: gpio_in.
 * 							- 1: gpio_out.
 * @return					- 0 : OK
 *							- -1: ERRO
 **********************************************************************/
int gpio_set_dir(int portNum,int bitValue,int dir)
{
	int fd, req;
	fd = open(GPIO_DEV, O_RDONLY);
	if (fd < 0) {
		perror(GPIO_DEV);
		return -1;
	}
	if (dir == gpio_in) {
		if (portNum == gpio9564)
			req = RALINK_GPIO9564_SET_DIR_IN;
		else if (portNum == gpio6332)
			req = RALINK_GPIO6332_SET_DIR_IN;
		else
			req = RALINK_GPIO_SET_DIR_IN;
	}
	else {
		if (portNum == gpio9564)
			req = RALINK_GPIO9564_SET_DIR_OUT;
		else if (portNum == gpio6332)
			req = RALINK_GPIO6332_SET_DIR_OUT;
		else

			req = RALINK_GPIO_SET_DIR_OUT;
	}
	if (ioctl(fd, req, bitValue) < 0) {
		perror("ioctl");
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}
/*********************************************************************//**
 * @brief		Read GPIO Value.
 * @param[in]	portNum		Port Number value
 *  						- 0(gpio3100):	GPIO bit 0 - 31
 *							- 1(gpio6332):	GPIO bit 32 - 63
 *							- 2(gpio9564): 	GPIO bit 64 - 95
 * @param[in]	*value		Value on the PortNum,
 * @return					- 0 : OK
 *							- -1: ERRO
 **********************************************************************/
int gpio_read_int(int portNum, int *value)
{
	int fd, req;

	*value = 0;
	fd = open(GPIO_DEV, O_RDONLY);
	if (fd < 0) {
		perror(GPIO_DEV);
		return -1;
	}
	if (portNum == gpio9564)
		req = RALINK_GPIO9564_READ;
	else if (portNum == gpio6332)
		req = RALINK_GPIO6332_READ;
	else
		req = RALINK_GPIO_READ;
	if (ioctl(fd, req, value) < 0) {
		perror("ioctl");
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}


/*********************************************************************//**
 * @brief		write GPIO Value.
 * @param[in]	portNum		Port Number value
 *  						- 0(gpio3100):	GPIO bit 0 - 31
 *							- 1(gpio6332):	GPIO bit 32 - 63
 *							- 2(gpio9564): 	GPIO bit 64 - 95
 * @param[in]	value		Value write the PortNum,
 * @return					-  0: OK
 *							- -1: ERRO
 **********************************************************************/
int gpio_write_int(int portNum, int value)
{
	int fd, req;
	fd = open(GPIO_DEV, O_RDONLY);
	if (fd < 0) {
		perror(GPIO_DEV);
		return -1;
	}
	if (portNum == gpio9564)
		req = RALINK_GPIO9564_WRITE;
	else if (portNum == gpio6332)
		req = RALINK_GPIO6332_WRITE;
	else
		req = RALINK_GPIO_WRITE;
	if (ioctl(fd, req, value) < 0) {
		perror("ioctl");
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}










